package com.huangfu.learning.javabase.java.pattern.action.strategy;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/8/7
 * Time: 15:33
 * Version: 1.0
 * Description: 策略模式 实现同一个接口。
 * 参考：https://blog.csdn.net/u012124438/article/details/70039943/
 * http://www.runoob.com/design-pattern/strategy-pattern.html
 * <p>
 * 优点： 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
 * 缺点： 1、策略类会增多。 2、所有策略类都需要对外暴露。
 * <p>
 * 使用场景：
 * 1、如果在一个系统里面有许多类，它们之间的区别仅在于它们的行为，那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
 * 2、一个系统需要动态地在几种算法中选择一种。
 * 3、如果一个对象有很多的行为，如果不用恰当的模式，这些行为就只好使用多重的条件选择语句来实现。
 **/
public class StrategyPattern {

    // 测试
    public static void main(String[] args) {
        // 加法，使用时，将实现类传入
        ContextFactory contextFactory = new ContextFactory(new OperationAdd());
        System.out.println(contextFactory.executeStrategy(3, 4));

        // 减法
        contextFactory = new ContextFactory(new OperationSubstract());
        System.out.println(contextFactory.executeStrategy(3, 4));

        // 乘法
        contextFactory = new ContextFactory(new OperationMultiply());
        System.out.println(contextFactory.executeStrategy(3, 4));
    }
}

/**
 * 接口
 */
interface Stratrgy {
    int doOperation(int num1, int num2);
}

/**
 * 实现类，实现加法运算
 */
class OperationAdd implements Stratrgy {

    @Override
    public int doOperation(int num1, int num2) {
        return num1 + num2;
    }
}

/**
 * 实现类，实现减法运算
 */
class OperationSubstract implements Stratrgy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 - num2;
    }
}

/**
 * 实现类，实现乘法运算
 */
class OperationMultiply implements Stratrgy {
    @Override
    public int doOperation(int num1, int num2) {
        return num1 * num2;
    }
}

/**
 * 策略工厂类
 */
class ContextFactory {

    private Stratrgy stratrgy;

    // 构造函数中的参数是接口，调用的时候传入实现类
    public ContextFactory(Stratrgy stratrgy) {
        this.stratrgy = stratrgy;
    }

    public int executeStrategy(int num1, int num2) {
        return stratrgy.doOperation(num1, num2);
    }
}